"use client";

import * as React from "react";

import * as ToolbarPrimitive from "@radix-ui/react-toolbar";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import { type VariantProps, cva } from "class-variance-authority";
import { ChevronDown } from "lucide-react";

import {
  DropdownMenuLabel,
  DropdownMenuRadioGroup,
  DropdownMenuSeparator,
} from "@/components/plate/ui/dropdown-menu";
import { Separator } from "@/components/plate/ui/separator";
import { Tooltip, TooltipTrigger } from "@/components/plate/ui/tooltip";
import { cn } from "@/lib/utils";

export function Toolbar({
  className,
  ...props
}: React.ComponentProps&lt;typeof ToolbarPrimitive.Root&gt;) {
  return (
    &lt;ToolbarPrimitive.Root
      className={cn("relative flex select-none items-center", className)}
      {...props}
    /&gt;
  );
}

export function ToolbarToggleGroup({
  className,
  ...props
}: React.ComponentProps&lt;typeof ToolbarPrimitive.ToolbarToggleGroup&gt;) {
  return (
    &lt;ToolbarPrimitive.ToolbarToggleGroup
      className={cn("flex items-center", className)}
      {...props}
    /&gt;
  );
}

export function ToolbarLink({
  className,
  ...props
}: React.ComponentProps&lt;typeof ToolbarPrimitive.Link&gt;) {
  return (
    &lt;ToolbarPrimitive.Link
      className={cn("font-medium underline underline-offset-4", className)}
      {...props}
    /&gt;
  );
}

export function ToolbarSeparator({
  className,
  ...props
}: React.ComponentProps&lt;typeof ToolbarPrimitive.Separator&gt;) {
  return (
    &lt;ToolbarPrimitive.Separator
      className={cn("mx-2 my-1 w-px shrink-0 bg-border", className)}
      {...props}
    /&gt;
  );
}

// From toggleVariants
const toolbarButtonVariants = cva(
  "inline-flex cursor-pointer items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-checked:bg-accent aria-checked:text-accent-foreground aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
  {
    defaultVariants: {
      size: "default",
      variant: "default",
    },
    variants: {
      size: {
        default: "h-9 min-w-9 px-2",
        lg: "h-10 min-w-10 px-2.5",
        sm: "h-8 min-w-8 px-1.5",
      },
      variant: {
        default: "bg-transparent",
        outline:
          "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
      },
    },
  },
);

const dropdownArrowVariants = cva(
  cn(
    "inline-flex items-center justify-center rounded-r-md text-sm font-medium text-foreground transition-colors disabled:pointer-events-none disabled:opacity-50",
  ),
  {
    defaultVariants: {
      size: "sm",
      variant: "default",
    },
    variants: {
      size: {
        default: "h-9 w-6",
        lg: "h-10 w-8",
        sm: "h-8 w-4",
      },
      variant: {
        default:
          "bg-transparent hover:bg-muted hover:text-muted-foreground aria-checked:bg-accent aria-checked:text-accent-foreground",
        outline:
          "border border-l-0 border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
      },
    },
  },
);

type ToolbarButtonProps = {
  isDropdown?: boolean;
  pressed?: boolean;
} & Omit&lt;
  React.ComponentPropsWithoutRef&lt;typeof ToolbarToggleItem&gt;,
  "asChild" | "value"
&gt; &
  VariantProps&lt;typeof toolbarButtonVariants&gt;;

export const ToolbarButton = withTooltip(function ToolbarButton({
  children,
  className,
  isDropdown,
  pressed,
  size = "sm",
  variant,
  ...props
}: ToolbarButtonProps) {
  return typeof pressed === "boolean" ? (
    &lt;ToolbarToggleGroup disabled={props.disabled} value="single" type="single"&gt;
      &lt;ToolbarToggleItem
        className={cn(
          toolbarButtonVariants({
            size,
            variant,
          }),
          isDropdown && "justify-between gap-1 pr-1",
          className,
        )}
        value={pressed ? "single" : ""}
        {...props}
      &gt;
        {isDropdown ? (
          &lt;&gt;
            <div>
              {children}
            </div>
            <div>
              &lt;ChevronDown
                className="size-3.5 text-muted-foreground"
                data-icon
              /&gt;
            </div>
          &lt;/&gt;
        ) : (
          children
        )}
      &lt;/ToolbarToggleItem&gt;
    &lt;/ToolbarToggleGroup&gt;
  ) : (
    &lt;ToolbarPrimitive.Button
      className={cn(
        toolbarButtonVariants({
          size,
          variant,
        }),
        isDropdown && "pr-1",
        className,
      )}
      {...props}
    &gt;
      {children}
    &lt;/ToolbarPrimitive.Button&gt;
  );
});

export function ToolbarSplitButton({
  className,
  ...props
}: React.ComponentPropsWithoutRef&lt;typeof ToolbarButton&gt;) {
  return (
    &lt;ToolbarButton
      className={cn("group flex gap-0 px-0 hover:bg-transparent", className)}
      {...props}
    /&gt;
  );
}

type ToolbarSplitButtonPrimaryProps = Omit&lt;
  React.ComponentPropsWithoutRef&lt;typeof ToolbarToggleItem&gt;,
  "value"
&gt; &
  VariantProps&lt;typeof toolbarButtonVariants&gt;;

export function ToolbarSplitButtonPrimary({
  children,
  className,
  size = "sm",
  variant,
  ...props
}: ToolbarSplitButtonPrimaryProps) {
  return (
    <span>
      {children}
    </span>
  );
}

export function ToolbarSplitButtonSecondary({
  className,
  size,
  variant,
  ...props
}: React.ComponentPropsWithoutRef&lt;"span"&gt; &
  VariantProps&lt;typeof dropdownArrowVariants&gt;) {
  return (
    <span> e.stopPropagation()}
      role="button"
      {...props}
    &gt;
      &lt;ChevronDown className="size-3.5 text-muted-foreground" data-icon /&gt;
    </span>
  );
}

export function ToolbarToggleItem({
  className,
  size = "sm",
  variant,
  ...props
}: React.ComponentProps&lt;typeof ToolbarPrimitive.ToggleItem&gt; &
  VariantProps&lt;typeof toolbarButtonVariants&gt;) {
  return (
    &lt;ToolbarPrimitive.ToggleItem
      className={cn(toolbarButtonVariants({ size, variant }), className)}
      {...props}
    /&gt;
  );
}

export function ToolbarGroup({
  children,
  className,
}: React.ComponentProps&lt;"div"&gt;) {
  return (
    <div>
      <div>{children}</div>

      <div>
        &lt;Separator orientation="vertical" /&gt;
      </div>
    </div>
  );
}

type TooltipProps&lt;T extends React.ElementType&gt; = {
  tooltip?: React.ReactNode;
  tooltipContentProps?: Omit&lt;
    React.ComponentPropsWithoutRef&lt;typeof TooltipContent&gt;,
    "children"
  &gt;;
  tooltipProps?: Omit&lt;
    React.ComponentPropsWithoutRef&lt;typeof Tooltip&gt;,
    "children"
  &gt;;
  tooltipTriggerProps?: React.ComponentPropsWithoutRef&lt;typeof TooltipTrigger&gt;;
} & React.ComponentProps&lt;T&gt;;

function withTooltip&lt;T extends React.ElementType&gt;(Component: T) {
  return function ExtendComponent({
    tooltip,
    tooltipContentProps,
    tooltipProps,
    tooltipTriggerProps,
    ...props
  }: TooltipProps&lt;T&gt;) {
    const [mounted, setMounted] = React.useState(false);

    React.useEffect(() =&gt; {
      setMounted(true);
    }, []);

    const component = &lt;Component {...(props as React.ComponentProps&lt;T&gt;)} /&gt;;

    if (tooltip && mounted) {
      return (
        &lt;Tooltip {...tooltipProps}&gt;
          &lt;TooltipTrigger asChild {...tooltipTriggerProps}&gt;
            {component}
          &lt;/TooltipTrigger&gt;

          &lt;TooltipContent {...tooltipContentProps}&gt;{tooltip}&lt;/TooltipContent&gt;
        &lt;/Tooltip&gt;
      );
    }

    return component;
  };
}

function TooltipContent({
  children,
  className,
  // CHANGE
  sideOffset = 4,
  ...props
}: React.ComponentProps&lt;typeof TooltipPrimitive.Content&gt;) {
  return (
    &lt;TooltipPrimitive.Portal&gt;
      &lt;TooltipPrimitive.Content
        className={cn(
          "origin-(--radix-tooltip-content-transform-origin) z-50 w-fit text-balance rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground",
          className,
        )}
        data-slot="tooltip-content"
        sideOffset={sideOffset}
        {...props}
      &gt;
        {children}
        {/* CHANGE */}
        {/* &lt;TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" /&gt; */}
      &lt;/TooltipPrimitive.Content&gt;
    &lt;/TooltipPrimitive.Portal&gt;
  );
}

export function ToolbarMenuGroup({
  children,
  className,
  label,
  ...props
}: React.ComponentProps&lt;typeof DropdownMenuRadioGroup&gt; & { label?: string }) {
  return (
    &lt;&gt;
      &lt;DropdownMenuSeparator
        className={cn(
          "hidden",
          "mb-0 shrink-0 peer-has-[[role=menuitem]]/menu-group:block peer-has-[[role=menuitemradio]]/menu-group:block peer-has-[[role=option]]/menu-group:block",
        )}
      /&gt;

      &lt;DropdownMenuRadioGroup
        {...props}
        className={cn(
          "hidden",
          "peer/menu-group group/menu-group my-1.5 has-[[role=menuitem]]:block has-[[role=menuitemradio]]:block has-[[role=option]]:block",
          className,
        )}
      &gt;
        {label && (
          &lt;DropdownMenuLabel className="select-none text-xs font-semibold text-muted-foreground"&gt;
            {label}
          &lt;/DropdownMenuLabel&gt;
        )}
        {children}
      &lt;/DropdownMenuRadioGroup&gt;
    &lt;/&gt;
  );
}
